template <class T>
Vector3<T>::Vector3(const Vector3<T>& other)
{
	x = other.x;
	y = other.y;
	z = other.z;
}

template <class T>
inline Vector3<T>& Vector3<T>::operator=(const Vector3<T>& other)
{
	x = other.x;
	y = other.y;
	z = other.z;
	return (*this);
}

template <class T>
inline T& Vector3<T>::operator[](unsigned int i)
{
	assert(0 <= i && i < 3);
	switch(i)
	{
	case 0:
		return x;
	case 1:
		return y;
	default:
		return z;
	}
}

template <class T>
inline Vector3<T> Vector3<T>::operator-() const
{
	Vector3<T> v;
	v.x = -x;
	v.y = -y;
	v.z = -z;
	return v;
}

template <class T>
inline Vector3<T> Vector3<T>::operator+( const Vector3<T>& other ) const
{
	Vector3<T> r;
	r.x = x + other.x;
	r.y = y + other.y;
	r.z = z + other.z;
	return r;
}

template <class T>
inline Vector3<T>& Vector3<T>::operator+=( const Vector3<T>& other )
{
	x += other.x;
	y += other.y;
	z += other.z;
	return (*this);
}

template <class T>
inline Vector3<T> Vector3<T>::operator*( T scalar ) const
{
	Vector3<T> r;
	r.x = x * scalar;
	r.y = y * scalar;
	r.z = z * scalar;
	return r;
}

template <class T>
inline Vector3<T> Vector3<T>::operator/(T scalar) const
{
	Vector3<T> r;

	if (abs(T) < EPSILON) return;

	r.x = x / scalar;
	r.y = y / scalar;
	r.z = z / scalar;
	return r;
}

template <class T>
inline Vector3<T>& Vector3<T>::operator*=(T scalar)
{
	x *= scalar;
	y *= scalar;
	z *= scalar;
	return (*this);
}

template <class T>
inline Vector3<T>& Vector3<T>::operator-=(const Vector3<T>& other)
{
	x -= other.x;
	y -= other.y;
	z -= other.z;
	return (*this);
}

template <class T>
inline Vector3<T> Vector3<T>::operator-(const Vector3<T>& other) const
{
	Vector3<T> r;
	r.x = x - other.x;
	r.y = y - other.y;
	r.z = z - other.z;
	return (r);
}

template <class T>
inline bool Vector3<T>::operator==(const Vector3<T>& other) const
{
	return (x == other.x && y == other.y && z == other.z);
}

template <class T>
inline bool Vector3<T>::operator!=(const Vector3<T>& other) const
{
	return (x != other.x || y != other.y || z != other.z)
}

template <class T>
inline void Vector3<T>::normalize()
{
	T lt = length();
	x = x / lt;
	y = y / lt;
	z = z / lt;
}

template <class T>
inline bool Vector3<T>::isZero() const
{
	return (x == 0 && y == 0 && z == 0);
}

template <class T>
inline T Vector3<T>::lengthSquared() const
{
	return (x * x + y * y + z * z);
}

template <class T>
inline T Vector3<T>::length() const
{
	return sqrt(x * x + y * y + z * z);
}

template <class T>
inline T Vector3<T>::dot( const Vector3<T>& vector ) const
{
	T result = x * vector.x + y * vector.y + z * vector.z;
	return result;
}

template <class T>
T Vector3<T>::dot( const Vector3<T>& vector1, const Vector3<T>& vector2 )
{
	T result = vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;
	return result;
}

template <class T>
inline Vector3<T> Vector3<T>::cross( const Vector3<T>& other ) const
{
	Vector3<T> result;
	result.x = y * other.z - other.y * z;
	result.y = -(x * other.z - other.x * z);
	result.z = x * other.y - y * other.x;
	return result;
}

template <class T>
Vector3<T> Vector3<T>::cross( const Vector3<T>& vector1, const Vector3<T>& vector2 )
{
	Vector3<T> result;
	result.x = vector1.y * vector2.z - vector2.y * vector1.z;
	result.y = -(vector1.x * vector2.z - vector2.x * vector1.z);
	result.z = vector1.x * vector2.y - vector1.y * vector2.x;
	return result;
}

template <class T>
inline void Vector3<T>::set( T _x, T _y, T _z )
{
	x = _x; y = _y; z = _z;
}

template <class T>
inline void Vector3<T>::zero()
{
	x = y = z = 0.0f;
}